import { generateUUID } from '../../utils'
import { addReadyProduct } from '../core/ReadyProducts'
import { schedule } from '../core/Scheduler'
import { currentTime } from '../core/SimulationClock'
import { messageTransfer } from '../messaging/MessageTransfer'
import { randomTime } from '../types'
import BaseStation from './BaseStation'
import Product from './Product'

class DisassemblyStation extends BaseStation {
  processTime: randomTime
  dismantlingQuantity: number
  private splitProduts: Product[] = []
  productWidth: number
  productHeight: number

  constructor(
    id: string,
    name: string,
    x: number,
    y: number,
    width = 100,
    height = 100,
    processTime: randomTime,
    dismantlingQuantity: number,
    productWidth: number = 20,
    productHeight: number = 20
  ) {
    super(id, name, x, y, width, height)
    this.processTime = processTime
    this.dismantlingQuantity = dismantlingQuantity
    this.productWidth = productWidth
    this.productHeight = productHeight
  }

  public canReceiveProduct(): boolean {
    return this.status === 'idle'
  }

  protected onProductReceived(product: Product): void {
    messageTransfer('product', 'move', { targetId: this.id, productId: product.id })
    messageTransfer('product', 'startProcessing', { targetId: this.id, productId: product.id })
    console.log(`[${currentTime}] ${product.id} 到达拆解站 --> ${this.name}`)
    this.tryDisassamble(product)
  }

  private tryDisassamble(product: Product): void {
    this.setStatus('processing')
    const time = typeof this.processTime === 'function' ? this.processTime() : this.processTime
    schedule(time, () => this.disassemble(product), `${this.id} 拆解 ${product.id}`)
  }

  private disassemble(product: Product): void {
    console.log(`[${currentTime}] ${this.name} 拆出 ${this.dismantlingQuantity} 个部件`)
    messageTransfer('product', 'recycle', {
      targetId: this.id,
      productId: product.id
    })

    const parts: Product[] = []
    for (let i = 0; i < this.dismantlingQuantity; i++) {
      const newPart = new Product(generateUUID(), this.productWidth, this.productHeight)
      newPart.setFrom(this.id)
      parts.push(newPart)
      messageTransfer('product', 'generate', { targetId: this.id, productId: newPart.id })
    }

    this.splitProduts = parts
    this.setStatus('block')
  }

  public tryDispatchCurrentProduct(): void {
    if (this.nextStations.length < this.dismantlingQuantity) {
      console.warn(`[${currentTime}] ⚠️ ${this.id} 的下游站点数量不足`)
      return
    }

    let mark = false
    for (const next of this.nextStations) {
      if (!next.canReceiveProduct(this.id, this.splitProduts[0])) {
        mark = true
        break
      }
    }

    if (mark) {
      console.log(`[${currentTime}] ⛔ ${this.name} 下游不空闲，等待中...`)
      return
    } else {
      for (let i = 0; i < this.splitProduts.length; i++) {
        const product = this.splitProduts[i]
        const station = this.nextStations[i]
        addReadyProduct(product)
        station.receiveReadyProduct(product.id)
      }

      this.setStatus('idle')
    }
  }
}

export default DisassemblyStation
